package com.ltmonitor.web.controller.video;

import com.ltmonitor.entity.BasicData;
import com.ltmonitor.entity.MediaItem;
import com.ltmonitor.entity.TerminalCommand;
import com.ltmonitor.service.IVideoFileItemService;
import com.ltmonitor.service.JT808Constants;
import com.ltmonitor.util.Constants;
import com.ltmonitor.util.DateUtil;
import com.ltmonitor.util.StringUtil;
import com.ltmonitor.util.VideoDataType;
import com.ltmonitor.video.entity.VideoFileItem;
import com.ltmonitor.video.entity.VideoServerConfig;
import com.ltmonitor.web.controller.command.TerminalCommandAction;
import com.ltmonitor.web.util.JsonMessage;
import com.ltmonitor.web.vo.VideoFile;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * 下发查询终端音视频资源列表命令
 * 
 * @author DELL
 * 
 */
@Controller
@RequestMapping("/videoResourceSearch")
public class VideoResourceSearchAction extends TerminalCommandAction {
	@Autowired
	private IVideoFileItemService videoFileItemService;
	
	@RequestMapping("/view.action")
	public String view(long vehicleId, Model m)
	{
		m.addAttribute("vehicleId", vehicleId);
		return "/video/videoResourceList";
	}


	/**
	 * 下发查询资源列表指令
	 * @param vehicleId
	 * @param channel
	 * @param startDate
	 * @param endDate
	 * @param alarmStatus 报警标志
	 * @param videoType 音视频资源类型
	 * @param streamType 码流类型
	 * @param storeType 存储器类型
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/sendRequest.action")
	public JsonMessage sendRequest(int vehicleId, int videoType, int streamType, String alarmStatus, int storeType,
								   int channel, Date startDate, Date endDate) {

		try {
			long alarm  = 0;
			if(StringUtil.isNullOrEmpty(alarmStatus) == false) {
				String[] strAlarms = alarmStatus.split(",");
				byte[] alarmArray = new byte[64];
				for(String strAalrm:strAlarms)
				{
					int bit = Integer.parseInt(strAalrm);
					alarmArray[bit] = 1;
				}

				StringBuilder sb = new StringBuilder();
				for(byte b : alarmArray)
				{
					sb.append(b);
				}
				sb.reverse();
				alarm = Long.valueOf(sb.toString(), 2); // 将位数组转换为字节值
			}
			StringBuilder sb = new StringBuilder();
			sb.append(channel).append(';')
					.append(DateUtil.datetimeToString(startDate)).append(';')
					.append(DateUtil.datetimeToString(endDate)).append(';')
					.append(alarm).append(';').append(videoType).append(';')
					.append(streamType).append(';').append(storeType);

			TerminalCommand tc = new TerminalCommand();
			tc.setCmdType(0x9205);
			tc.setCmdData(sb.toString());
			tc.setVehicleId(vehicleId);
			SendCommand(tc);

			return json(true, tc.getEntityId());
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			return json(false, ex.getMessage());
		}
	}

	/**
	 * 根据指令ID，获取终端返回的多媒体记录数据列表
	 * @param commandId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/getVideoResourceList.action")
	public JsonMessage getVideoResourceList(long commandId) {
		try {
			TerminalCommand tc = getTerminalCommand(commandId);
			BasicData bd = getBasicDataService().getBasicDataByCode(
					tc.getStatus(), "TCommandStatus");
			String status = bd != null ? bd.getName() : "";
			Map result = new HashMap();
			result.put("status", status);
			if (TerminalCommand.STATUS_SUCCESS.equals(tc.getStatus())) {
				List<VideoFileItem> data = this.videoFileItemService.getVideoFileItemListByCommandId(commandId);
				List<Map> r = new ArrayList<Map>();
				for(VideoFileItem v : data)
				{
					Map h = new HashMap();
					h = BeanUtils.describe(v);
					long alarmState = v.getAlarmStatus();
					String strAlarmState = this.getVideoAlarmDescr(alarmState);
					h.put("alarmStatus", strAlarmState);
					this.convert(h,"streamType", "StreamType");
					this.convert(h,"dataType", "VideoResourceType");
					this.convert(h,"storeType", "StoreType");

					double d = v.getFileLength() / 1024;
					String sizeDescr = Constants.formatFileSize(""+d);
					h.put("fileLength", sizeDescr);
					r.add(h);
				}
				result.put("data", r);
				return json(true, result);
			} else if (TerminalCommand.STATUS_NEW.equals(tc.getStatus()) == false
					&& TerminalCommand.STATUS_PROCESSING.equals(tc.getStatus()) == false) {
				return json(true, status);
			} else {
				return json(false, status);
			}
		} catch (Exception ex) {
			log.error(ex.getMessage());
			log.error(ex.getStackTrace());
			return json(false, "查询时发送错误:" + ex.getMessage());
		}
	}


	/**
	 * 下发服务器录像指令
	 * @param simNo
	 * @param channelId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/startRecord.action")
	public JsonMessage startRecord(String simNo, int channelId) {
		try {
			VideoFileItem vi = new VideoFileItem();
			simNo = simNo.length() > 11 ? simNo.substring(1) : simNo;
			vi.setSimNo(simNo);
			vi.setChannelId((byte)channelId);
			vi.setFileSource(VideoFileItem.FROM_USER);
			vi.setStatus(VideoFileItem.STATUS_NOT_UPLOAD);

			this.videoFileItemService.saveOrUpdate(vi);
			this.putSession(simNo + "_" + channelId, vi.getEntityId());
			return json(true,"请求成功");
		} catch (Exception ex) {
			log.error(ex.getMessage(),ex);
			return json(false, "用户发起录像请求，出现错误:" + ex.getMessage());
		}
	}


	/**
	 * 下发服务器结束录像指令
	 * @param simNo
	 * @param channelId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/endRecord2.action")
	public ResponseEntity<byte[]> endRecord2(String simNo, int channelId) {
		try {
			simNo = (simNo.length() > 11 ? simNo.substring(1) : simNo);
			this.videoFileItemService.endRecordFile(simNo, channelId);
			VideoFileItem vi = null;
			int times = 0;
			while(vi == null && times++ < 20)
			{
				Thread.sleep(100);
				vi = this.videoFileItemService.getRecordFile(simNo, channelId);
			}

			if(vi == null)
			{
				log.error("文件没有录像完成");
				return null;
			}
			String strDir = this.getVideoServerConfig().getFtpPath() + "\\" + vi.getFilePath();
			File file = new File(strDir);
			//String path="F:\\rtp120180102140113.txt";
			//File file=new File(path);
			HttpHeaders headers = new HttpHeaders();
			String fileName = new String(file.getName().getBytes("UTF-8"), "iso-8859-1");//为了解决中文名称乱码问题
			headers.setContentDispositionFormData("attachment", fileName);
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			byte[] d = FileUtils.readFileToByteArray(file);
			return new ResponseEntity<byte[]>(d,
					headers, HttpStatus.CREATED);
		} catch (Exception ex) {
			log.error(ex.getMessage(),ex);
			return null;
		}
	}

	/**
	 * 在视频播放窗口上下发结束服务器录像指令
	 * @param simNo
	 * @param channelId
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping("/endRecord.action")
	public void endRecord(String simNo, int channelId,
						HttpServletRequest request,
						HttpServletResponse response) throws IOException {
		try {
			simNo = (simNo.length() > 11 ? simNo.substring(1) : simNo);
			this.videoFileItemService.endRecordFile(simNo, channelId);


			Long id = (Long)this.getFromSession(simNo + "_" + channelId);
			if(id == null)
				return;

			VideoFileItem vi = null;
			int times = 0;
			while((vi == null || VideoFileItem.STATUS_UPLOAD_COMPLTETED.equals(vi.getStatus()) == false) && times++ < 20)
			{
				Thread.sleep(100);
				vi = this.videoFileItemService.load(id);
			}

			if(vi == null)
			{
				log.error(vi.getFilePath() + "文件没有录像完成");
				return;
			}
			String strDir = this.getVideoServerConfig().getFtpPath() + "\\" + vi.getFilePath();
			File file = new File(strDir);
			//String path="F:\\rtp120180102140113.txt";
			//File file=new File(path);
			HttpHeaders headers = new HttpHeaders();
			String fileName = new String(file.getName().getBytes("UTF-8"), "iso-8859-1");//为了解决中文名称乱码问题
			headers.setContentDispositionFormData("attachment", fileName);
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			byte[] d = FileUtils.readFileToByteArray(file);
			FileInputStream inputStream = new FileInputStream(file);
			byte[] data = new byte[(int)file.length()];
			int length = inputStream.read(data);
			inputStream.close();

			response.setContentType("video/mpeg4; charset=utf-8");
			response.setHeader("Content-Disposition", "attachment;filename="  + vi.getFilePath());

			OutputStream stream = response.getOutputStream();
			stream.write(data);
			stream.flush();
			stream.close();
		} catch (Exception ex) {
			log.error(ex.getMessage(),ex);
		}
	}


}
